package com.ruoyi.flowable.cmd;


import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;

import java.util.List;

/*
    退流程,2021-04-24,dustball   退流程是退到指定历史节点,同时结束当前所有节点，痕迹保留
 */
public class RefuseFlowCmd implements Command<String> {

    //退回时，是否触发结束所有进行中的任务，默认结束
    private boolean isEndAll = true;

    //当前任务
    private TaskEntity currentTaskEntity;

    //要驳回的历史节点
    private TaskEntity hisTaskEntity;

    public RefuseFlowCmd(boolean isEndAll, TaskEntity currentTaskEntity, TaskEntity hisTaskEntity) {
        this.isEndAll = isEndAll;
        this.currentTaskEntity = currentTaskEntity;
        this.hisTaskEntity = hisTaskEntity;
    }

    public RefuseFlowCmd(TaskEntity currentTaskEntity, TaskEntity hisTaskEntity) {
        this.currentTaskEntity = currentTaskEntity;
        this.hisTaskEntity = hisTaskEntity;
    }

    @Override
    public String execute(CommandContext commandContext) {
        String ProcessDefinitionId = this.currentTaskEntity.getProcessDefinitionId();
        BpmnModel bpmnModel = CommandContextUtil.getProcessEngineConfiguration(commandContext).getRepositoryService().getBpmnModel(ProcessDefinitionId);
        //目标建模节点信息
        FlowElement targetFlowElement = bpmnModel.getFlowElement(this.hisTaskEntity.getTaskDefinitionId());
        ExecutionEntity currentExecutionEntity = CommandContextUtil.getExecutionEntityManager(commandContext).findById(currentTaskEntity.getExecutionId());
        if (!isEndAll){
            currentTaskEntity.setExecutionId(null);
            CommandContextUtil.getTaskService(commandContext).deleteTask(currentTaskEntity, false);
        }else{
            //找兄弟节点结束，后续补充
            List<ExecutionEntity> tempList=CommandContextUtil.getExecutionEntityManager(commandContext).findChildExecutionsByProcessInstanceId(currentTaskEntity.getProcessInstanceId());
            tempList.remove(currentExecutionEntity);
            for (ExecutionEntity e:tempList){
                CommandContextUtil.getExecutionEntityManager(commandContext).delete(e);
            }
            List<TaskEntity> taskList=CommandContextUtil.getTaskService(commandContext).findTasksByProcessInstanceId(currentTaskEntity.getProcessInstanceId());
            for (TaskEntity t:taskList){
                CommandContextUtil.getTaskService(commandContext).deleteTask(t,false);
            }
        }

        currentExecutionEntity.setCurrentFlowElement(targetFlowElement);
        CommandContextUtil.getExecutionEntityManager(commandContext).update(currentExecutionEntity);
        CommandContextUtil.getTaskService(commandContext).insertTask(hisTaskEntity, false);
        return "";
    }
}
